package com.k2data.k2app.service;

import com.k2data.k2app.domain.SysMenu;
import com.k2data.k2app.exception.K2ResponseException;
import com.k2data.k2app.mapper.SysMenuMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 */
@Log4j2
@Service
public class SysMenuService {

    private final SysMenuMapper sysMenuMapper;

    @Autowired
    public SysMenuService(SysMenuMapper testMapper) {
        this.sysMenuMapper = testMapper;
    }

    @Transactional
    public long insert(SysMenu sysMenu) throws K2ResponseException {
        //TODO :login user
        sysMenu.setCreateBy("");
        sysMenu.setUpdateBy("");
        sysMenuMapper.insertOfSelective(sysMenu);
        return sysMenu.getId();
    }

    @Transactional
    public int update(SysMenu sysMenu) throws K2ResponseException {
        //TODO :login user
        sysMenu.setUpdateBy("");
        int num = sysMenuMapper.updateByPrimaryKeySelective(sysMenu);
        return num;
    }

    @Transactional
    public List<SysMenu> menuGroup(Long parentId,Boolean isTree) throws K2ResponseException {
        List<SysMenu> menus = sysMenuMapper.queryList();
        if(isTree != null && isTree){
            return buildTree(parentId,menus);
        }else{
            return menus;
        }
    }

    /**
     * 使用递归方法建树
     * @param parentId 父类id
     * @param treeNodes
     * @return
     */
    public List<SysMenu> buildTree(Long parentId,List<SysMenu> treeNodes) {
        List<SysMenu> trees = new ArrayList<>();
        Long pId = parentId == null?0:parentId;
        treeNodes.stream().filter(item -> item.getParentId() == pId).forEach(item -> {
            trees.add(findChildren(item,treeNodes));
        });
        if(pId==0){
            return addToTopMenu(trees);
        } else {
          return trees;
        }
    }

    /**
     * 递归查找子节点
     * @param treeNodes
     * @return
     */
    public static SysMenu findChildren(SysMenu treeNode,List<SysMenu> treeNodes) {
        treeNodes.stream().filter(item -> item.getParentId() == treeNode.getId()).forEach(item -> {
            System.out.println(treeNode.getId()+"  :"+item.getId());
            if (treeNode.getChildren() == null) {
                treeNode.setChildren(new ArrayList<>());
            }
            treeNode.getChildren().add(findChildren(item,treeNodes));
        });
        return treeNode;
    }


    @Transactional
    public List<SysMenu> getMenusByUser(Long userId,Boolean isTree){
        List<SysMenu> menus = sysMenuMapper.queryByUserId(userId);
        List<SysMenu> menus1 = new ArrayList<>();
        List<Long> menuids = new ArrayList<>();
        // 找到没有关联到的父类节点
        for(SysMenu sysMenu:menus){
           if(sysMenu.getParentId()!=0 && !menuids.contains(sysMenu.getParentId())){
               List<SysMenu> sysMenus = getParent(sysMenu);
               for(SysMenu sysMenu1:sysMenus){
                   if(!menuids.contains(sysMenu1.getId())){
                       menuids.add(sysMenu1.getId());
                       menus1.add(sysMenu1);
                   }
               }
               menuids.add(sysMenu.getId());
               menus1.add(sysMenu);
           }else{
               if(!menuids.contains(sysMenu.getId())){
                   menuids.add(sysMenu.getId());
                   menus1.add(sysMenu);
               }
           }
        }
        // 转换为树形格式
        if(isTree != null && isTree){
            List<SysMenu> trees = buildTree(null,menus1);
//            return addToTopMenu(trees);
              sortTree(trees);
              return trees;
        }else{
            return menus1;
        }
    }

    /**
     * 递归查询所有父级元素，直到第一级为止
     * @param sysMenu
     * @return
     */
    public List<SysMenu>  getParent(SysMenu sysMenu){
        List<SysMenu> sysMenus = new ArrayList<>();
        if(sysMenu.getParentId() == 0){
            return sysMenus;
        }
        SysMenu sysMenu1 = sysMenuMapper.getById(sysMenu.getParentId());
        List<SysMenu> menus = getParent(sysMenu1);
        sysMenus.add(sysMenu1);
        sysMenus.addAll(menus);
        return sysMenus;
    }


    @Transactional
    public List<SysMenu> getMenusByRole(Long userId,Boolean isTree){
        List<SysMenu> menus = sysMenuMapper.queryByRoleId(userId);
        if(isTree != null && isTree){
            List<SysMenu> trees = buildTree(null,menus);
            return trees;
        }else{
            return menus;
        }
    }

    public List<SysMenu> addToTopMenu(List<SysMenu> sysMenus){
        SysMenu sysMenu = new SysMenu();
        sysMenu.setId(0l);
        sysMenu.setName("功能菜单");
        sysMenu.setChildren(sysMenus);
        List<SysMenu> list = new ArrayList<>();
        list.add(sysMenu);
        return list;
    }

    public void sortTree(List<SysMenu> list){
        Collections.sort(list, new Comparator<SysMenu>() {
            @Override
            public int compare (SysMenu o1, SysMenu o2) {
                return (int) (o1.getSort()-o2.getSort());
            }
        });
        for(SysMenu sysMenu:list){
            if(sysMenu.getChildren().size()>0){
                sortTree(sysMenu.getChildren());
            }
        }
    }
}
